Skip to content

build(deps): make the torch CUDA build a uv group choice - #26

Open
gdevenyi wants to merge 1 commit into
FlashML-org:mainfrom
gdevenyi:pyproject-cu126-group
Open

build(deps): make the torch CUDA build a uv group choice#26
gdevenyi wants to merge 1 commit into
FlashML-org:mainfrom
gdevenyi:pyproject-cu126-group

Conversation

@gdevenyi

@gdevenyi gdevenyi commented Aug 22, 2026

Copy link
Copy Markdown

The problem

[tool.uv.sources] pins torch to the cu130 index unconditionally, so uv sync in a checkout can only resolve the CUDA 13 build.

CUDA 13 dropped Maxwell, Pascal and Volta. Its wheels carry no cubin below sm_75. On a pre-Turing card that resolution produces a torch that cannot address the GPU at all.

What this changes

The CUDA build becomes a group choice. cu130 stays the default, so nothing changes for anyone on supported hardware.

uv sync                                    # torch 2.11.0+cu130   (unchanged)
uv sync --no-default-groups --group cu126  # torch 2.11.0+cu126   (pre-Turing)

No version constraint moves. torch 2.11.0+cu126 exists on the pytorch index and already satisfies the torch>=2.11,<2.12 range. Its arch list is sm_50, 60, 70, 75, 80, 86 and 90, and the sm_60 cubin runs on sm_61 under CUDA's minor-version binary compatibility guarantee.

Verified against the real dependency set

130 packages resolved. All three paths checked:

$ uv export                                     | grep ^torch==
torch==2.11.0+cu130
$ uv export --no-default-groups --group cu126   | grep ^torch==
torch==2.11.0+cu126
$ uv export --group cu126 --group cu130
error: Groups `cu126` and `cu130` are incompatible with the conflicts:
       {`freetoken:cu126`, `freetoken:cu130`}

The groups are declared conflicting, so the two can never resolve into one environment. Asking for both is a clean error rather than a silent winner.

Why groups and not extras

Extras work, but every source entry then has to be disambiguated. uv rejects a list with one bare fallback entry, reporting Requirements contain conflicting indexes for package torch in all marker environments.

With extras there is no way to leave cu130 as the unconditional default, so a plain uv sync would fall back to PyPI instead of the pinned index. That changes the provenance of torch for every existing user. default-groups = ["cu130"] keeps today's behaviour exactly.

Testing

This changes dependency resolution only, so it has no unit test. The three uv export commands above are the check, and they are cheap to re-run.

`[tool.uv.sources]` pinned torch to the cu130 index unconditionally, so `uv sync` in
a checkout could only ever resolve the CUDA 13 build. CUDA 13 dropped Maxwell, Pascal
and Volta, and its wheels carry no cubin below sm_75, so on a pre-Turing card that
resolution produces a torch that cannot address the GPU at all.

Split the pin into two conflicting dependency groups. cu130 is the default group, so
a plain `uv sync` resolves byte-for-byte as it did before; a pre-Turing GPU asks for
the other one:

    uv sync --no-default-groups --group cu126

torch 2.11.0+cu126 exists on the pytorch index and satisfies the existing
`torch>=2.11,<2.12` range, so no version constraint moves. Its arch list is
sm_50/60/70/75/80/86/90, and the sm_60 cubin runs on sm_61 under CUDA's
minor-version binary compatibility guarantee.

Declaring the groups conflicting means the two can never resolve into one
environment; asking for both is a clean error rather than a silent winner.

`sglang-kernel` keeps its single cu130 pin deliberately: it publishes cu130 wheels
only and its AOT kernels are sm_75+ regardless, so a pre-Turing install leaves the
`sgl` extra off (same for flashinfer's `fi`) and falls back to the pure-triton
kernels.

Verified against the real dependency set (130 packages resolved):

    uv export                                    -> torch==2.11.0+cu130
    uv export --no-default-groups --group cu126   -> torch==2.11.0+cu126
    uv export --group cu126 --group cu130         -> error: groups are incompatible

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KQy3DziJN9peJ7nA8L59ns
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant